﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using t_TestingLibrary;
using System.ComponentModel.Composition;
using System.IO;
using PaperRenderingInterfaces;
using HTMLTablePageScanner;
using RenderEngineInterfaces;
using DeepZoomPivotConstructor.VisualLib;
using System.Drawing;
using DeepZoomPivotConstructor.PivotLib;
using PaperPluginUtilities;
using System.Diagnostics;
using t_PivotGeneratorTestHelpers;

namespace t_HTMLTablePageScanner
{
    [TestClass]
    public class t_PlotPageScanner
    {
        [TestInitialize]
        public void TestSetup()
        {
            Utilities.MyClassInit();
        }

        [TestCleanup]
        public void TestCleanup()
        {
            Utilities.MyClassDone();
        }

        /// <summary>
        /// Hunt throught the metadata!
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="pmf"></param>
        /// <param name="p"></param>
        /// <returns></returns>
        private T1[] FindMetadata<T1>(PivotImage pmf, string p)
            where T1 : PivotMetadataBase
        {
            var md = from m in pmf
                     where m.Name == p && m.GetType() == typeof(T1)
                     let masType = (T1)m
                     where masType != null
                     select masType;
            return md.ToArray();
        }

        [Export(typeof(IRenderEngine))]
        class RenderEngineDummy : IRenderEngine
        {
            public System.Threading.Tasks.Task<DeepZoomPivotConstructor.VisualLib.Visual> RenderToFuture(object what, Type[] disallowRenderPlugins = null, bool forceAsComposableUnit = false,
                bool requestComposableUnit = false)
            {
                throw new NotImplementedException();
            }

            List<string> whatWeSaw = new List<string>();
            public DeepZoomPivotConstructor.VisualLib.Visual Render(object what, Type[] disallowRenderPlugins = null, bool forceAsComposableUnit = false, bool requestComposableUnit = false)
            {
                Visual v = new VisualBitmapImage(1.0, 1.0, 100, Color.Black);
                if (forceAsComposableUnit)
                {
                    v.SetAsComposableUnit(null);
                }
                System.Diagnostics.Trace.WriteLine("Rendering " + what.ToString());
                whatWeSaw.Add(what.ToString());
                return v;
            }

            private void Trace(string p)
            {
                throw new NotImplementedException();
            }

            /// <summary>
            /// Did we see something as one of our requests?
            /// </summary>
            /// <param name="p"></param>
            /// <returns></returns>
            internal bool SawRequest(string p)
            {
                return whatWeSaw.Contains(p);
            }
        }

        [TestMethod]
        public void TestCtor()
        {
            PlotPageScanner t = new PlotPageScanner();
        }

        [TestMethod]
        public void TestCDFZJetsQCD()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\cdf_zjets_qcd.html") };
            Utilities.AddPart(laf);
            Utilities.AddPart(new RenderEngineDummy());
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/qcd/Zjets_mumu2010/index.html");
            Assert.AreEqual("http://www-cdf.fnal.gov/physics/new/qcd/Zjets_mumu2010/index.html", laf.UrlAskedFor, "URL request is incorrect");

            var results = result.ToArray();

            Assert.AreEqual(11, results.Count(), "Unexpected nubmer of images");

            Assert.IsTrue(results.All(r => r.Image.IsCompositionUnit), "Not all are compositional units!");
            Assert.AreEqual(0, results.Count(r => r.Name == "eps"), "Some of the titles are eps!");
            Assert.AreEqual(0, results.Count(r => FindMetadata<PivotMetadataURL>(r, "Graphics Files").Count() == 0), "Some guys don't have enough graphics files");
            Assert.IsTrue(results.Count(r => FindMetadata<PivotMetadataURL>(r, "More Information").Count() != 1) == 0, "Some don't have a link to main page!");
            Assert.IsTrue(results.Count(r => FindMetadata<PivotMetadataDateTime>(r, "Date").Count() != 1) == 0, "Some don't have a date");
            Assert.AreEqual(0, results.Count(r => FindMetadata<PivotMetadataString>(r, "Note Title").Count() != 1), "Not everyone had a note title");
            Assert.AreEqual(0, results.Count(r => FindMetadata<PivotMetadataString>(r, "Caption").Count() != 1), "Not everyone had a caption either!");
            ImageChecks.CheckNameAndDescription(results);
        }

        [TestMethod]
        public void TestCDFPSPi()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\cdfbspi.htm") };
            Utilities.AddPart(laf);
            Utilities.AddPart(new RenderEngineDummy());
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/bottom/100304.blessed-Bsphiphi_amplitudes/index.html");
            var results = result.ToArray();
            ImageChecks.CheckNameAndDescription(results);
        }

        [TestMethod]
        public void TestForRelativeURLS()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\BsPhiPhi.html") };
            Utilities.AddPart(laf);
            var red = new RenderEngineDummy();
            Utilities.AddPart(red);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/bottom/090618.blessed-Bsphiphi2.9");
            var results = result.ToArray();

            Assert.IsTrue(red.SawRequest("http://www-cdf.fnal.gov/physics/new/bottom/090618.blessed-Bsphiphi2.9/cdf10064_BsPhiPhi_BR.pdf"), "Didn't see a url request for the pdf I expected!");
            ImageChecks.CheckNameAndDescription(results);
        }

        [TestMethod]
        public void TestForRelativeURLSWithTrailingSlash()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\BsPhiPhi.html") };
            Utilities.AddPart(laf);
            var red = new RenderEngineDummy();
            Utilities.AddPart(red);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/bottom/090618.blessed-Bsphiphi2.9/");
            var results = result.ToArray();

            Assert.IsTrue(red.SawRequest("http://www-cdf.fnal.gov/physics/new/bottom/090618.blessed-Bsphiphi2.9/cdf10064_BsPhiPhi_BR.pdf"), "Didn't see a url request for the pdf I expected!");
            ImageChecks.CheckNameAndDescription(results);
        }

        [TestMethod]
        public void TestForRelativeURLSWithIndex()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\BsPhiPhi.html") };
            Utilities.AddPart(laf);
            var red = new RenderEngineDummy();
            Utilities.AddPart(red);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/bottom/090618.blessed-Bsphiphi2.9/index.html");
            var results = result.ToArray();

            Assert.IsTrue(red.SawRequest("http://www-cdf.fnal.gov/physics/new/bottom/090618.blessed-Bsphiphi2.9/cdf10064_BsPhiPhi_BR.pdf"), "Didn't see a url request for the pdf I expected!");
            ImageChecks.CheckNameAndDescription(results);
        }

        [TestMethod]
        public void TestForNoWeirdLigatureCharacters()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\mass.htm") };
            Utilities.AddPart(laf);
            var red = new RenderEngineDummy();
            Utilities.AddPart(red);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/top/2009/mass/TMT_AH_P19_public/TMT_AH_3fb.html");
            var results = result.ToArray();

            results.Execute(r => Trace.WriteLine("name: " + r.Name));

            Assert.IsTrue(results.All(r => r.Name.All(c => !char.IsControl(c) || c == '\t')), "Some characters are control characters!");
            ImageChecks.CheckNameAndDescription(results);
        }

        [TestMethod]
        public void TestNoTitleInHTML()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\blessed_plots.html") };
            Utilities.AddPart(laf);
            var red = new RenderEngineDummy();
            Utilities.AddPart(red);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/bottom/090903.blessed-Upsilon1S-polarization/blessed_plots.html");
            var results = result.ToArray();
            ImageChecks.CheckNameAndDescription(results);
        }

        [TestMethod]
        public void TestMailToInLinks()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\charm-xsection.html") };
            Utilities.AddPart(laf);
            var red = new RenderEngineDummy();
            Utilities.AddPart(red);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/bottom/060921.blessed-double-charm-corr/");
            var results = result.ToArray();
            ImageChecks.CheckNameAndDescription(results);
        }

        [TestMethod]
        public void TestNullInfo()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\heavy-baryon.html") };
            Utilities.AddPart(laf);
            var red = new RenderEngineDummy();
            Utilities.AddPart(red);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/bottom/060921.blessed-double-charm-corr/");
            var results = result.ToArray();
            ImageChecks.CheckNameAndDescription(results);
        }

        [TestMethod]
        public void TestNullInfoOnWidget()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\widget1_markup.html") };
            Utilities.AddPart(laf);
            var red = new RenderEngineDummy();
            Utilities.AddPart(red);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/hdg/Results_files/widget1_markup.html");
            var results = result.ToArray();
            Assert.IsTrue(results.All(r => r.Name.All(c => !char.IsControl(c) || c == '\t')), "Some characters are control characters!");
            ImageChecks.CheckNameAndDescription(results);
        }

        [TestMethod]
        public void TestMetadataClash()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\cdf-single-top.html") };
            Utilities.AddPart(laf);
            var red = new RenderEngineDummy();
            Utilities.AddPart(red);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/top/public_singletop.html");
            var results = result.ToArray();
            Assert.IsTrue(results.All(r => r.Name.All(c => !char.IsControl(c) || c == '\t')), "Some characters are control characters!");
            ImageChecks.CheckNameAndDescription(results);
        }

        [TestMethod]
        public void TestNoNoteTitle()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\cdf-ratio-DKDpi.html") };
            Utilities.AddPart(laf);
            var red = new RenderEngineDummy();
            Utilities.AddPart(red);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/bottom/060420.blessed-BDK-decay/");
            var results = result.ToArray();

            Assert.IsTrue(results.All(r => r.Where(md => md.Name == "Note Title").Count() == 0), "Found some note titles! What the heck!? THis web page has no title in it!");
            ImageChecks.CheckNameAndDescription(results);
        }

        [TestMethod]
        public void TestNoEPSGIFigureNames()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\rparity.html") };
            Utilities.AddPart(laf);
            var red = new RenderEngineDummy();
            Utilities.AddPart(red);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/exotic/r2a/20090709.rpv_sneutrino_emu_etau_mutau/lfv_9405.html");
            var results = result.ToArray();

            results.Execute(r => Trace.WriteLine("Picture name: " + r.Name));
            Assert.IsFalse(results.Any(r => r.Name.ToLower() == "eps"), "Some figures had name 'eps'");
            Assert.IsFalse(results.Any(r => r.Name.ToLower() == "gif"), "Some figures had name 'gif'");
            ImageChecks.CheckNameAndDescription(results);
        }

        [TestMethod]
        public void TestNoEPSOrGIFInFigureNames()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\exclusive-dijet.html") };
            Utilities.AddPart(laf);
            var red = new RenderEngineDummy();
            Utilities.AddPart(red);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/exotic/r2a/20090709.dijetmet/dijet_met_2fb.html");
            var results = result.ToArray();

            ImageChecks.CheckNameAndDescription(results);
        }

        [TestMethod]
        public void TestBadImageDates()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\exclusive-dijet.html") };
            laf.DateToReturn = DateTime.Now;
            Utilities.AddPart(laf);
            var red = new RenderEngineDummy();
            Utilities.AddPart(red);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/exotic/r2a/20090709.dijetmet/dijet_met_2fb.html");
            var results = result.ToArray();

            ImageChecks.CheckNameAndDescription(results);
            ImageChecks.CheckForStandardMetadata(results);
        }

        [Export(typeof(IWebAccess))]
        public class BadUrlNullRtn : IWebAccess
        {
            public string GetUriAsString(Uri whatToLoad)
            {
                return "";
            }

            public DateTime? GetLastModificationTime(Uri whatToCheck)
            {
                throw new NotImplementedException();
            }
        }

        [TestMethod]
        public void TestUrlNotFound()
        {
            PlotPageScanner target = new PlotPageScanner();
            Utilities.AddPart(new BadUrlNullRtn());
            var red = new RenderEngineDummy();
            Utilities.AddPart(red);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/top/public/dilepton/testSM-dil/public.html");
            var results = result.ToArray();
            Assert.AreEqual(0, results.Count(), "Expected nothing back at all!");
        }

        [TestMethod]
        public void TestOnCFile()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\XsecSumPlotFull.C") };
            Utilities.AddPart(laf);
            var red = new RenderEngineDummy();
            Utilities.AddPart(red);
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/ewk/xsec_plot/XsecSumPlotFull.C");
            var results = result.ToArray();

            Assert.AreEqual(0, results.Count(), "Expected zero for the count");

        }

        [TestMethod]
        public void TestCDFHGammaGammaPage()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\cdfhgammagammaplots.html") };
            Utilities.AddPart(laf);
            Utilities.AddPart(new RenderEngineDummy());
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/hdg//Results_files/results/hgamgam_jan10/plots.html");
            var results = result.ToArray();
            Assert.AreEqual(6, results.Length, "Wrong number of images came back from the higgs to gamma gamma!");
            ImageChecks.CheckNameAndDescription(results);
        }

        [TestMethod]
        public void TestCDFZGammaPage()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\cdf-zgamma.html") };
            Utilities.AddPart(laf);
            Utilities.AddPart(new RenderEngineDummy());
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/ewk/2009/zgamma/ZgammaWebPage/index.html");
            var results = result.ToArray();
            Assert.AreEqual(38, results.Length, "Wrong number of images came back from the higgs to gamma gamma!");
            ImageChecks.CheckNameAndDescription(results);
        }

        [TestMethod]
        public void TestCDFEtabForPNGTitles()
        {
            PlotPageScanner target = new PlotPageScanner();
            var laf = new LoadAFile() { theFileToLoad = new FileInfo("..\\..\\..\\t_HTMLTablePageScanner\\cdf_search_for_etab.html") };
            Utilities.AddPart(laf);
            Utilities.AddPart(new RenderEngineDummy());
            Utilities.Compose(target);

            var result = target.Render("http://www-cdf.fnal.gov/physics/new/bottom/060615.blessed-etab/");
            var results = result.ToArray();
            ImageChecks.CheckNameAndDescription(results);
        }
    }
}
